/*
 * Copyright 2011 Andrew Freer
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "resources.h"
#include "globals.h"
#include "main_dialog.h"
#include "directxfiles_tab.h"
#include "utility.h"
#include "sound_tab.h"
#include <assert.h>
#include <windows.h>
#include <commctrl.h>
#include <winuser.h>
#include <stdio.h>
/* mingw is missing some definitions */
#ifndef LVCFMT_COL_HAS_IMAGES
#define LVCFMT_COL_HAS_IMAGES   0x8000
#endif                          /*  */

/* Local constants */
RECT dlus;
int CALLBACK directxfile_compare(LPARAM lParam1, LPARAM lParam2,
                                 LPARAM lParamSort)
{
    DxDiag_DirectXFiles *directXFiles = g_dxdiagcom_root.directXFiles;
    DxDiag_DirectXFile *left, *right;
    INT paramSort = (INT) lParamSort;
    BOOL ascending = TRUE;
    INT compareVal;
    long numLeft, numRight;
    left = directXFiles->directXFiles[lParam1];
    right = directXFiles->directXFiles[lParam2];

    /* Sort ascending/descending */
    printf("paramSort original %d\n", paramSort);
    if (paramSort < 0) {
        paramSort *= -1;
        ascending = FALSE;
    }
    paramSort--;                /* Swap to 0 index */
    printf("paramSort %d\n", paramSort);
    switch (paramSort) {
    case DIRECTXFILES_COL_NAME:
        compareVal = lstrcmpW(left->szName, right->szName);
        break;
    case DIRECTXFILES_COL_ATTRIBUTES:
        compareVal = lstrcmpW(left->szAttributes, right->szAttributes);
        break;
    case DIRECTXFILES_COL_DATE:
        compareVal =
            lstrcmpW(left->szDatestampLocalized,
                     right->szDatestampLocalized);
        break;
    case DIRECTXFILES_COL_LANGUAGE:
        compareVal =
            lstrcmpW(left->szLanguageLocalized,
                     right->szLanguageLocalized);
        break;
    case DIRECTXFILES_COL_SIZE:
        numLeft = lstrtolW(left->lNumBytes, NULL, 10);
        numRight = lstrtolW(right->lNumBytes, NULL, 10);
        if (numLeft < numRight)
            compareVal = -1;

        else if (numLeft > numRight)
            compareVal = 1;

        else
            compareVal = 0;
        break;
    case DIRECTXFILES_COL_VERSION:
        compareVal = lstrcmpW(left->szVersion, right->szVersion);
        break;
    default:
        assert(FALSE);
        break;
    }

    /* Invert if necessary */
    if (ascending) {
        return compareVal;
    } else {
        return compareVal * -1;
    }
}

INT_PTR CALLBACK directxfiles_tab_dialog_proc(HWND hwnd, UINT message,
                                              WPARAM wParam, LPARAM lParam)
{
    static INT lastColSorted = -1;
    static BOOL sortAscending = FALSE;
    int sortParam;
    DxDiag_DirectXFile *directXFile;
    NMLVDISPINFOW *plvdi;
    NMLISTVIEW *pNm;
    switch (message) {
    case WM_NOTIFY:
        switch (((LPNMHDR) lParam)->code) {
        case LVN_GETDISPINFOW:
            plvdi = (NMLVDISPINFOW *) lParam;
            directXFile
                =
                g_dxdiagcom_root.directXFiles->directXFiles[plvdi->item.
                                                            lParam];
            switch (plvdi->item.iSubItem) {
            case DIRECTXFILES_COL_NAME:
                plvdi->item.pszText = (WCHAR*)get_safe_string(directXFile->szName);
                if (lstrcmpW(directXFile->bProblem, LSTRING_COMMON_TRUE)
                    == 0) {
                    plvdi->item.iImage = 0;
                }
                break;
            case DIRECTXFILES_COL_VERSION:
                plvdi->item.pszText = directXFile->szVersion;
                break;
            case DIRECTXFILES_COL_ATTRIBUTES:
                plvdi->item.pszText = directXFile->szAttributes;
                break;
            case DIRECTXFILES_COL_LANGUAGE:
                plvdi->item.pszText = directXFile->szLanguageLocalized;
                break;
            case DIRECTXFILES_COL_DATE:
                plvdi->item.pszText = directXFile->szDatestampLocalized;
                break;
            case DIRECTXFILES_COL_SIZE:
                plvdi->item.pszText = directXFile->lNumBytes;
                break;
            default:
                assert(FALSE);
            }
            break;
        case LVN_COLUMNCLICK:

            /* Sort inversion */
            pNm = (NMLISTVIEW *) lParam;
            if (lastColSorted >= 0 && lastColSorted == pNm->iSubItem) {
                sortAscending = !sortAscending;
            } else {
                sortAscending = TRUE;
                lastColSorted = pNm->iSubItem;
            }

            /* Convert parameter. Add one to disambiguate column 0 */
            sortParam = (pNm->iSubItem) + 1;
            if (!sortAscending) {
                sortParam *= -1;
            }
            SendMessageW(pNm->hdr.hwndFrom, LVM_SORTITEMS,
                         (WPARAM) (sortParam),
                         (LPARAM) directxfile_compare);
        default:
            return FALSE;
        }
    default:
        return FALSE;
    }
    return TRUE;
}

VOID resize_directxfiles_tab(HWND hTab, RECT displayArea)
{
    HWND handle;
    LONG width, height;
    LONG notesGbTop, notesGbHeight, notesGbWidth, notesGbLeft;
    LONG notesTop, notesHeight, notesWidth, notesLeft;
    LONG filesTop, filesLeft, filesWidth, filesHeight;

    /* Set dialog size */
    width = displayArea.right - displayArea.left;
    height = displayArea.bottom - displayArea.top;
    SetWindowPos(hTab, NULL, displayArea.left, displayArea.top, width,
                 height, 0);

    /* Set notes groupbox */
    notesGbLeft = WND_DEF_SPACING;
    notesGbWidth = width - 2 * WND_DEF_SPACING;
    notesGbHeight = 5 * dlus.bottom;
    notesGbTop = height - notesGbHeight - WND_DEF_SPACING;
    handle = GetDlgItem(hTab, DLG_DIRXFILES_NOTES_GB);
    SetWindowPos(handle, NULL, notesGbLeft, notesGbTop, notesGbWidth,
                 notesGbHeight, 0);

    /* Set notes edit */
    notesLeft = notesGbLeft + WND_DEF_SPACING;
    notesTop = notesGbTop + 1.5 * dlus.bottom;
    notesWidth = notesGbWidth - 2 * WND_DEF_SPACING;
    notesHeight = notesGbTop + notesGbHeight - notesTop - WND_DEF_SPACING;
    handle = GetDlgItem(hTab, DLG_DIRXFILES_NOTES);
    SetWindowPos(handle, NULL, notesLeft, notesTop, notesWidth,
                 notesHeight, 0);

    /* Set files list control */
    filesTop = WND_DEF_SPACING;
    filesLeft = WND_DEF_SPACING;
    filesWidth = width - 2 * WND_DEF_SPACING;
    filesHeight = notesGbTop - 2 * WND_DEF_SPACING;
    handle = GetDlgItem(hTab, DLG_DIRXFILES_FILES);
    SetWindowPos(handle, NULL, filesLeft, filesTop, filesWidth,
                 filesHeight, 0);
}

VOID create_directxfiles_tab(Tab * tab)
{
    HWND hTab, dirXFilesView;
    LVCOLUMNW lvc;
    HRESULT hr;
    HICON hiconItem;
    HIMAGELIST hSmall;
    int iCol, iRow;
    LVITEMW lvI;
    WCHAR *text;
    int columnIds[] = { STRING_COMMON_NAME, STRING_COMMON_VERSION,
        STRING_COMMON_ATTRIBUTES, STRING_COMMON_LANGUAGE,
        STRING_COMMON_DATE,
        STRING_COMMON_SIZE
    };
    DxDiag_DirectXFiles *directXFiles = g_dxdiagcom_root.directXFiles;

    /* Create dialog */
    hTab =
        CreateDialogW(g_hinstance, MAKEINTRESOURCEW(DLG_DIRECTXFILES),
                      g_hmaindialog, directxfiles_tab_dialog_proc);
    if (hTab == NULL) {
        messageboxw_resource(g_hmaindialog,
                             STRING_ERROR_DIRXFILES_DIALOG_CREATE,
                             STRING_COMMON_ERROR,
                             MB_OK | MB_ICONEXCLAMATION);
        return;
    }

    /* Get dialog units */
    dlus.left = 0;
    dlus.right = DLG_UNIT_DEF_WIDTH;
    dlus.top = 0;
    dlus.bottom = DLG_UNIT_DEF_HEIGHT;
    MapDialogRect(hTab, &dlus);

    /* Initialize tab */
    tab_initialize(tab, hTab, resize_directxfiles_tab);

    /* Notes Groupbox */
    set_control_text_resource(hTab, STRING_NOTES, DLG_DIRXFILES_NOTES_GB);

    /* Notes */
    set_control_text(hTab, directXFiles->szDXFileNotesLocalized,
                     DLG_DIRXFILES_NOTES);

    /* List images */
    dirXFilesView = GetDlgItem(hTab, DLG_DIRXFILES_FILES);
    hSmall =
        ImageList_Create(GetSystemMetrics(SM_CXSMICON),
                         GetSystemMetrics(SM_CYSMICON), ILC_MASK, 1, 1);
    hiconItem = LoadIconW(NULL, MAKEINTRESOURCEW(IDI_WARNING));
    ImageList_AddIcon(hSmall, hiconItem);
    DestroyIcon(hiconItem);
    SendMessageW(dirXFilesView, LVM_SETIMAGELIST, (WPARAM) LVSIL_SMALL,
                 (LPARAM) hSmall);

    /* List header */
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    lvc.cx = dlus.right * 15;
    lvc.fmt = LVCFMT_LEFT;
    for (iCol = 0; iCol < DIRECTXFILES_COL_COUNT; iCol++) {
        lvc.iSubItem = iCol;
        LoadStringW(g_hinstance, columnIds[iCol], (WCHAR*)&text, 0);
        lvc.pszText = text;
        hr = SendMessageW(dirXFilesView, LVM_INSERTCOLUMNW, (WPARAM) iCol,
                          (LPARAM) & lvc);
    }

    /* Fill DirectXFiles list */
    lvI.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM | LVIF_IMAGE;
    lvI.iSubItem = 0;
    lvI.state = 0;
    lvI.stateMask = 0;
    lvI.pszText = LPSTR_TEXTCALLBACKW;
    lvI.iImage = I_IMAGECALLBACK;
    for (iRow = 0; iRow < directXFiles->numDirectXFiles; iRow++) {
        lvI.iItem = iRow;
        lvI.lParam = (LPARAM) iRow;
        hr = SendMessageW(dirXFilesView, LVM_INSERTITEMW, 0,
                          (LPARAM) & lvI);
    }
}
